package com.niu.crm.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONArray;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.niu.crm.service.BaseService;
import com.niu.crm.service.DictService;
import com.niu.crm.core.error.BizException;
import com.niu.crm.core.error.GlobalErrorCode;
import com.niu.crm.dao.mapper.DictMapper;
import com.niu.crm.model.User;
import com.niu.crm.model.Dict;

@Service
public class DictServiceImpl extends BaseService implements DictService {
	private Map<Long,Dict> cacheById = null;
	private Map<String,Dict> cacheByCode = null;
	
    @Autowired
    private DictMapper  dictMapper;
	
    @Override
   	public void refrechCache(){
    	cacheById = null;
    	cacheByCode = null;
    }
    
    private void refreshCache(Long id, String code){
    	if( cacheById == null){
    		cacheById = new HashMap<Long, Dict>();
    		cacheByCode = new HashMap<String, Dict>();
    	}
    	if(id==null && StringUtils.isBlank(code))
    		return;
    	
    	Dict dict = null;
    	if(null != id )
    		dict = dictMapper.selectById(id);
    	else 
    		dict = dictMapper.selectByCode(code);
    	
    	if(dict == null)
    		this.getLogger().error("dict not found id=" + id + " code=" + code);
    	
    	if( dict != null){
    		cacheById.put(dict.getId(), dict);
    		cacheByCode.put(dict.getDictCode(), dict);
    	}
    }
    
    @Override
	public Dict load(Long id){
		return load(id,null);
	}
    
    @Override
	public Dict loadByCode(String code){
    	return load(null, code);
	}
    
    private Dict load(Long id, String code){
    	Dict dict = null;
    	if( null != cacheById ){
    		if(null != id )
        		dict = cacheById.get(id);
        	else 
        		dict = cacheByCode.get(code); 
    	}
    	
    	if(dict == null){
    		refreshCache(id, code);
    		if(null != id )
        		dict = cacheById.get(id);
        	else 
        		dict = cacheByCode.get(code);  
    	}
    	
    	return dict;
    }
    
    
    @Override
	public void delete(User user, Long id){
		dictMapper.delete(id);
	}

    @Override
    public List<Dict> loadChildren(String parentCode){
    	Dict pDict = loadByCode(parentCode.toLowerCase()); 
    	if(pDict == null)
    		getLogger().error("dict not exists code=" + parentCode);
    	
    	return loadChildren(pDict.getId());
    }

    @Override
    public List<Dict> loadChildren(Long parentId){
    	List<Dict> ls = dictMapper.selectChildren(parentId);
    	
    	return ls;
    }
    
    @Override
    public List<Dict> selectByName(String codePrefix, String dictName){
    	return dictMapper.selectByName(codePrefix, dictName);
    }

    
    @Override
    public JSONArray getJSONTree(Long parentId){
    	/*
    	if(tree == null)
    		loadJSONTree();
    	
    	return tree; */
    	return loadJSONTree(parentId);
    }
    
    @Override
    public JSONArray loadJSONTree(Long parentId){
    	List<Dict> children = loadChildren(parentId);
    	
    	return childTree(children, true);
    }
    
    @Override
	public boolean isAncestorDict(Dict ancestorDict, Dict dict){	
		if(dict.getParentId() == null)
			return false;
		
		Long id = ancestorDict.getId();		
		Dict pDict = this.load(dict.getParentId());
		while(pDict !=null){
			if(pDict.getId().equals(id))
				return true;
			
			if(pDict.getParentId() == null)
				break;
			pDict = this.load(pDict.getParentId());
		}
		return false;
	}
	
    
    /**
     * @param children
     * @param topLevel  是否是tree第一层
     * @return
     */
    private JSONArray childTree(List<Dict> children, boolean topLevel){
    	JSONArray jTree = new JSONArray();
    	if(children == null || children.size() ==0)
    		return jTree;
    	    	
    	for(int i=0; i < children.size(); i++){
    		Dict dict = children.get(i);
    		JSONObject node = new JSONObject();
    		node.put("id", dict.getId() );
    		node.put("code", dict.getDictCode() );
    		node.put("text", dict.getDictName() );
    		
    		
        	jTree.add(node);
        	
        	List<Dict> ls = loadChildren(dict.getId());
        	if(ls.size() >0){
        		node.put("state", "closed" );	
        		node.put("children", childTree(ls, false));
        	}
    	}    
    	return jTree;
    }
    
    private String getAliasFromCode(String dictCode){
    	if(StringUtils.isEmpty(dictCode))
    		return null;
    	
    	int idx = dictCode.lastIndexOf(".");
    	if(idx <0)
    		return dictCode;
    	else
    		return dictCode.substring(idx +1);
    	
    }
}
